/**
 * 
 */
package com.testvideo.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.JWindow;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.testvideo.command.ClipInfoChangeEvent;
import com.testvideo.command.ClipInfoChangeListener;
import com.testvideo.command.VideoClipInfo;

/**
 * @author Administrator
 *
 */
public class PlayerToolBarPanel extends JPanel implements ClipInfoChangeListener{

	private JButton playPauseButton ;
	private JButton stopButton ;
	private JButton quickInButton ;
	
	private JButton openFileButton ;
	private JButton fullScreenButton ;
	
	private JSlider volumeProgress ;
	
	private JProgressBar timeProgress ;
	private JFrame parent ;	
	
	private FleetPlayer fleet ;
	
	/**现在进度条是否正在被拖动，如果是，则应停止来自mplayer的时间更新请求。*/
	private boolean timeDragInProcess = false ;
	
	public PlayerToolBarPanel(JFrame parent){
		this.parent = parent ;
		setupUI() ;
	}
	
	/**注册事件机制，完成初始化。*/
	public void registerLinks(FleetPlayer fp){
		this.fleet = fp ;
		VideoClipInfo ci = fp.getPlayer().getVideoClipInfo() ;
		ci.addClipInfoChangeListener(this) ;		

		pm = new PlayingMonitor() ;
		pm.start() ;
		
		initActions() ;
	}
	
	private void setupUI(){
		playPauseButton = new JButton("开始播放") ;
		stopButton = new JButton("停止") ;
		quickInButton = new JButton("快进") ;

		openFileButton = new JButton("打开电影") ;
		fullScreenButton = new JButton("全屏播放") ;
		
		volumeProgress = new JSlider() ;
		volumeProgress.setMinimum(0) ;
		volumeProgress.setMaximum(100) ;
		volumeProgress.setValue(0) ;
		
		JPanel timeLine = new JPanel() ;
		timeLine.setLayout(new BorderLayout()) ;
		timeLine.setBackground(Color.BLACK) ;
		timeLine.setSize(parent.getWidth(), 3) ;
		
		timeProgress = new JProgressBar() ;
		timeProgress.setBackground(Color.BLACK) ;
		timeProgress.setMinimum(0) ;
		timeProgress.setOrientation(JProgressBar.HORIZONTAL) ;
		timeProgress.setFocusable(true) ;
		timeProgress.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)) ;
		
		timeLine.add(timeProgress, BorderLayout.CENTER) ;
		
		JPanel actionPanel = new JPanel() ;
		actionPanel.add(playPauseButton) ;
		actionPanel.add(stopButton) ;
		actionPanel.add(quickInButton) ;
		actionPanel.add(openFileButton) ;
		actionPanel.add(fullScreenButton) ;
		actionPanel.add(volumeProgress) ;
		
		this.setLayout(new BorderLayout()) ;
		this.add(timeLine, BorderLayout.NORTH) ;
		this.add(actionPanel, BorderLayout.CENTER) ;		
	}
	
	public void initActions(){
		playPauseButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				fleet.getPlayer().play() ;
			}
		}) ;
		
		stopButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				notifyPlayTerminate() ;
				fleet.getPlayer().stop() ;				
			}
		}) ;
		
		openFileButton.setAction(new OpenVideoFileAction(parent, fleet)) ;
		
		timeProgress.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				int seconds = totalLengthInSeconds * e.getX() / timeProgress.getWidth() ;
				setUserChoosedTime(seconds) ;
			}

			public void mousePressed(MouseEvent e) {
				timeProgress.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) ;
			}

			public void mouseReleased(MouseEvent e) {
				timeProgress.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)) ;
				timeDragInProcess = false ;
			}
			
			
		}) ;
		
		timeProgress.addMouseMotionListener(new MouseMotionAdapter(){			
			private int xNow ;
			private int xOld ;
			private long lastSeekTime ;
			private AutoSeekThread seeker = new AutoSeekThread() ;
			
			{
				seeker.start() ;
			}
			
			public void mouseDragged(MouseEvent e) {
				xNow = e.getX() ;
			}
			
			class AutoSeekThread extends Thread{
				
				public AutoSeekThread(){
					this.setDaemon(true) ;
				}
				
				public void run(){
					//在mouse在drag时，每隔200毫秒进行一次progress刷新，每隔500毫秒seek video
					while(true){
						if(xOld != xNow){ //被拖动了
							long now = System.currentTimeMillis() ;
							xOld = xNow ;
							timeDragInProcess = true ;
							int seconds = totalLengthInSeconds * xNow / timeProgress.getWidth() ;
							
							if(now - lastSeekTime > 500){
								setUserChoosedTime(seconds) ;
								lastSeekTime = System.currentTimeMillis() ;
							}else{
								timeProgress.setValue(seconds) ;
							}
						}
						
						synchronized (this) {
							try {
								wait(200) ;
							} catch (InterruptedException e) {
							}
						}
					}
				}				
			}
			
		}) ;
		
		volumeProgress.addChangeListener(new ChangeListener(){

			public void stateChanged(ChangeEvent e) {
				int volumeNow = volumeProgress.getValue() ;
				
				if(volumeNow != volume){
					volume = volumeNow ;
					volumeProgress.setValue(volumeNow) ;
					fleet.getPlayer().setVoice(volumeNow) ;
				}
			}
			
		}) ;
		
		
		
		//注册全屏监听
		this.fullScreenButton.addActionListener(new ActionListener(){

			int i = 1 ;
			
			public void actionPerformed(ActionEvent e) {
				Graphics2D g =  (Graphics2D) fleet.getCanvas().getGraphics() ;
				g.setColor(Color.RED) ;
				g.drawString("Hello Word " + i++ , 100, 100) ;
				
				
//				isFullScreen = !isFullScreen ;
//				
////				fleet.getPlayer().activeFullScreen(isFullScreen) ;
//								
//				GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment() ;
//				GraphicsDevice gd = ge.getDefaultScreenDevice() ;
//				
//				if(gd.isFullScreenSupported()){
//					
//					Dimension screnSize = Toolkit.getDefaultToolkit().getScreenSize() ;
//					
//					fleet.getCanvas().setBounds(0, 0, (int)screnSize.getWidth(), (int)screnSize.getHeight()) ;
//					
//					fleet.getCanvas().getParent().remove(fleet.getCanvas()) ;
//					
//					w.setBounds(0, 0, (int)screnSize.getWidth(), (int)screnSize.getHeight()) ;
//					w.setVisible(true) ;
//					w.getContentPane().add(fleet.getCanvas()) ;
//					
////					parent.setVisible(false) ;
////					parent.dispose() ;
////					parent.setUndecorated(true) ;
////					parent.pack() ;
////					fleet.getCanvas().invalidate() ;
////					parent.setVisible(true) ;
//					
////					gd.setFullScreenWindow(parent) ;
////					fleet.getPlayer().restartPlay() ;					
//				}else{
//					System.out.println("full screen is not supported.");
//				}				
			}
			
		}) ;
		
		//注册全屏退出方式
		fleet.getCanvas().addKeyListener(new KeyAdapter(){
			public void keyReleased(KeyEvent e) {
				System.out.println("key char is:" + e.getKeyChar() + ";code is:" + e.getKeyCode() + ";ascii:" + e.getKeyText(e.getKeyCode())) ;
				
				if(e.getKeyCode() == 27){ //ESC key
					GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment() ;
					GraphicsDevice gd = ge.getDefaultScreenDevice() ;
//					fleet.getPlayer().activeFullScreen(false) ;
					
					if(gd.getFullScreenWindow() != null){
						isFullScreen = false ;
						
						parent.setVisible(false) ;
						parent.dispose() ;
						parent.setUndecorated(false) ;
						parent.pack() ;
						fleet.getCanvas().invalidate() ;
						parent.setVisible(true) ;
						gd.setFullScreenWindow(parent) ;
						
						fleet.getPlayer().restartPlay() ;
					}
				}else if(e.getKeyCode() == 32){ //backspace key
					fleet.getPlayer().play() ;
				}
			}
			
		}) ;
		
	}
	
	JWindow w = new JWindow() ;
	
	public void setUserChoosedTime(int seconds){
		if(seconds != nowPosInSeconds){
			timeProgress.setValue(seconds) ;
			
//			System.out.println("seek to :" + seconds + "/" + this.totalLengthInSeconds) ;
			
			//用户拖动了进度条
			fleet.getPlayer().seekTo(seconds) ;
		}
	}

	/**监听需要的视屏属性，对于属性的变化，只更新UI显示状态，不进行其他逻辑操作。*/
	public void updateClipInfo(ClipInfoChangeEvent evt) {
		//监听需要的视屏属性
		if(evt.match("ANS_LENGTH")){
			totalLengthInSeconds = (int) evt.getFloatValue() ;
			timeProgress.setMaximum(totalLengthInSeconds) ;
		}else if(evt.match("ANS_time_pos")){
			this.nowPosInSeconds = (int) evt.getFloatValue() ;
			
			if(!timeDragInProcess){
				timeProgress.setValue(this.nowPosInSeconds) ;
//				System.out.println("change to :" + this.nowPosInSeconds) ;
			}
			
			if(this.totalLengthInSeconds > 0 && this.nowPosInSeconds >= this.totalLengthInSeconds){
				//播放完毕
				this.isPause = true ;
			}
			
		}else if(evt.match("ANS_fullscreen")){
			boolean nowFull = evt.getBoolValue() ;
			if(nowFull == isFullScreen) return ;
			isFullScreen = nowFull ;
			if(isFullScreen){
				fullScreenButton.setText("退出全屏") ;
			}else{
				fullScreenButton.setText("全屏播放") ;
			}
		}else if(evt.match("ANS_pause")){
//			isPause = evt.getBoolValue() ; //command has delay, so this value will be always no.
			isPause = fleet.getPlayer().isPaused() ;
			if(isPause){
				notifyPlayPause() ;
			}else{
				notifyPlayResume() ;
			}
		}else if(evt.match("ANS_volume")){
			this.volume = (int) evt.getFloatValue() ;
			if(this.volume != this.volumeProgress.getValue()){
				this.volumeProgress.setValue(this.volume) ;
			}
		}else if(evt.match("ANS_speed")){
			this.speed = evt.getFloatValue() ;
		}else if(evt.match("ID_EXIT")){ //退出，或者播放结束。
			if("EOF".equalsIgnoreCase(evt.getValue())){
				//TODO: 正常播放结束，切换到下面一个视屏。
			}else{
				
			}
			notifyPlayTerminate() ;
		}
		
	}
	
	public void notifyPlayPause(){
		isPause = true ;
		this.playPauseButton.setText("开始播放") ;
	}
	
	public void notifyPlayResume(){
		isPause = false ;
		this.playPauseButton.setText("继续播放") ;
	}
	
	public void notifyPlayTerminate(){
		isPause = true ;
		this.playPauseButton.setText("开始播放") ;
		//set play area to a default image
	}
	
	private int totalLengthInSeconds ;
	private int nowPosInSeconds ;
	private float speed ;
	private boolean isPause = false ;
	private boolean isFullScreen = false ;
	private int volume ;
	
	private PlayingMonitor pm ;
	
	class PlayingMonitor extends Thread{
		
		public PlayingMonitor(){
			this.setDaemon(true) ;
		}
		
		public void run(){
			while(true){
				synchronized (this) {
					try {
						wait(1000) ;
						
						if(!isPause && fleet.getPlayer().isVideoLoaded() && !fleet.getPlayer().isPaused()){
							fleet.getPlayer().getPlayPositionNow() ;
						}
						
					} catch (Exception e) {
					}
				}
			}
		}
	}
	
}
